package com.gtenacg.cartoonservice.controller;

import com.gtenacg.cartoonservice.common.Result;
import com.gtenacg.cartoonservice.common.annotation.CheckToken;
import com.gtenacg.cartoonservice.pojo.model.*;
import com.gtenacg.cartoonservice.pojo.vo.CartoonVo;
import com.gtenacg.cartoonservice.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/cartoon")
@RequiredArgsConstructor
public class CartoonController {

    private final CartoonService cartoonService;
    private final CartoonTypeService typeService;
    private final RelationCartoonTypeService relationTypeService;
    private final RelationCartoonAuthorService relationAuthorService;
    private final AuthorService authorService;

    @GetMapping("/list")
    public Result<List<Cartoon>> list() {
        log.info("获取漫画列表");
        List<Cartoon> list = cartoonService.list();
        return Result.success(list);
    }

    @GetMapping("/search")
    public Result<List<Cartoon>> search(
            @RequestParam(required = false) String name
    ) {
        log.info("获取漫画列表, name:{}", name);
        List<Cartoon> list = cartoonService.search(name);
        return Result.success(list);
    }

    @GetMapping
    public Result<List<CartoonVo>> listToVo(
            @RequestParam(required = false) List<Integer> types
    ) {
        log.info("获取漫画视图列表, types:{}", types);
        List<Cartoon> cartoons = null;

        if (types == null || types.isEmpty()) {
            cartoons = cartoonService.list();
        } else {
            List<RelationCartoonType> byTids = relationTypeService.getByTids(types);
            List<Integer> cids = byTids.stream()
                    .map(RelationCartoonType::getCid)
                    .toList();
            cartoons = cartoonService.getByCids(cids);
        }
        List<CartoonVo> list = cartoonsToVo(cartoons);


        return Result.success(list);
    }

    @GetMapping("/searchVo")
    public Result<List<CartoonVo>> searchVo(@RequestParam String searchVal) {
        log.info("获取漫画视图列表, SearchVal:{}", searchVal);

        List<Cartoon> cartoons = cartoonService.search(searchVal);
        if (cartoons.isEmpty()) {
            return Result.success(new ArrayList<>());
        }
        List<CartoonVo> list = cartoonsToVo(cartoons);
        return Result.success(list);
    }

    @GetMapping("/randomVo")
    public Result<List<CartoonVo>> randomVo(
            @RequestParam(required = false, defaultValue = "4") Integer num
    ) {
        log.info("获取随机的漫画视图列表, num:{}", num);

        List<Cartoon> cartoons = cartoonService.random(num);
        List<CartoonVo> list = cartoonsToVo(cartoons);
        return Result.success(list);
    }

    @GetMapping("/{cids}")
    public Result<List<CartoonVo>> getVoByCids(@PathVariable List<Integer> cids) {
        log.info("获取指定cid为 {} 的视图列表", cids);

        List<Cartoon> cartoons = cartoonService.getByCids(cids);
        List<CartoonVo> list = cartoonsToVo(cartoons);

        return Result.success(list);
    }

    @GetMapping("/chapter/{cid}")
    public Result<List<String>> getChapterListByCid(@PathVariable Integer cid) {
        log.info("获取指定ID为 {} 的章节信息", cid);

        ArrayList<Integer> cids = new ArrayList<>();
        cids.add(cid);

        List<Cartoon> cartoons = cartoonService.getByCids(cids);
        List<String> chapterList = cartoonService.getChapterList(cartoons.get(0));

        return Result.success(chapterList);
    }

    @GetMapping("/chapter/{cid}/{chapterName}")
    public Result<List<String>> getChapterInfoByCid(@PathVariable Integer cid, @PathVariable String chapterName) {
        log.info("获取漫画ID为 {},章节名称为 {} 的信息", cid, chapterName);

        ArrayList<Integer> cids = new ArrayList<>();
        cids.add(cid);

        List<Cartoon> cartoons = cartoonService.getByCids(cids);
        List<String> chapterList = cartoonService.getChapterInfos(cartoons.get(0).getSrc() + chapterName + "/");

        return Result.success(chapterList);
    }

    @CheckToken
    @PostMapping
    public Result<Integer> insert(@RequestBody Cartoon cartoon) {
        log.info("新增漫画 {}", cartoon);
        Integer id = null;
        try {
            id = cartoonService.insert(cartoon);
        } catch (DuplicateKeyException e) {
            return new Result<>(HttpStatus.CONFLICT.value(), "Duplicate_Key", null);
        }
        return Result.success(id);
    }

    @CheckToken
    @PutMapping
    public Result<Void> update(@RequestBody Cartoon cartoon) {
        log.info("更新漫画 {}", cartoon);
        cartoonService.update(cartoon);
        return Result.success();
    }

    @CheckToken
    @DeleteMapping("/{cids}")
    public Result<Void> delete(@PathVariable List<Integer> cids) {
        log.info("删除漫画 {}", cids);
        cartoonService.delete(cids);
        return Result.success();
    }


    /**
     * 将漫画列表转化成视图列表
     */
    private List<CartoonVo> cartoonsToVo(List<Cartoon> cartoons) {
        if (cartoons == null || cartoons.isEmpty()) {
            return new ArrayList<>();
        }

        List<Integer> cids = cartoons.stream()
                .map(Cartoon::getCid)
                .toList();

        List<CartoonType> types = typeService.list();
        List<Author> authors = authorService.list();
        List<RelationCartoonType> relationTypes = relationTypeService.getByCids(cids);
        List<RelationCartoonAuthor> relationAuthors = relationAuthorService.getByCids(cids);

        return cartoonService.assembleCartoonVo(cartoons, types, relationTypes, authors, relationAuthors);
    }

}
